﻿//-----------------------------------------------------------------------
// <copyright file="Query.cs" company="Microsoft">
//     (c) 2009 Microsoft corp.
//     This software is distributed under Microsoft Public License (MSPL)
//     see http://opensource.org/licenses/ms-pl.html
// </copyright>
//-----------------------------------------------------------------------
namespace LiveSearchApiPowerToys.Components
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Json;
    using System.Text;
    using System.Web.Script.Serialization;

    using LiveSearchApiPowerToys.Components.net.live.search.api;

    /// <summary>
    /// A class representing a query to the Live Search service and abstracting some special tokens in the query
    /// string as strongly typed objects and fields
    /// </summary>
    [DataContract]
    public class Query
    {
        /// <summary>
        /// the query string text to pass to the search service
        /// </summary>
        private string txt;

        /// <summary>
        /// any custom augmentations that have to be sent to the search service
        /// </summary>
        private string augmentation;

        /// <summary>
        /// An identifier of a specific query pattern - used for caching
        /// </summary>
        private Guid cacheIdentifier;

        /// <summary>
        /// cache expiration time interval
        /// </summary>
        private TimeSpan cacheExpirationInterval;

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the Query class
        /// </summary>
        public Query()
        {
        }

        /// <summary>
        /// Initializes a new instance of the Query class
        /// </summary>
        /// <param name="queryText">the query string text to pass to the search service</param>
        /// <param name="queryAugmentation">any custom augmentations that have to be sent to the search service</param>
        public Query(string queryText, string queryAugmentation)
            : this()
        {
            this.Text = queryText;
            this.Augmentation = queryAugmentation;
        }

        /// <summary>
        /// Initializes a new instance of the Query class
        /// </summary>
        /// <param name="queryText">the query string text to pass to the search service</param>
        public Query(string queryText)
            : this()
        {
            this.Text = queryText;
            this.CacheIdentifier = Guid.Empty;
            this.CacheExpirationInterval = new TimeSpan(0, 30, 0);
        }
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets this Query expression - as string
        /// </summary>
        [DataMember]        
        public string Text
        {
            get { return this.txt; }
            set { this.txt = value; }
        }

        /// <summary>
        /// Gets or sets the Query augmentation. This is an extensibility mechanism.
        /// </summary>
        [DataMember]
        public string Augmentation
        {
            get { return this.augmentation; }
            set { this.augmentation = value; }
        }

        /// <summary>
        /// Gets or sets the Query Cache Identifier. This allows caching on the server side.
        /// </summary>
        [DataMember]
        public Guid CacheIdentifier
        {
            get { return this.cacheIdentifier; }
            set { this.cacheIdentifier = value; }
        }

        /// <summary>
        /// Gets or sets the Query Cache Expiration Interval. This supports cached query expiration on the server side.
        /// Default for this property is 30 minutes.
        /// </summary>        
        [DataMember]
        public TimeSpan CacheExpirationInterval
        {
            get { return this.cacheExpirationInterval; }
            set { this.cacheExpirationInterval = value; }
        }

        #endregion

        #region Serialization
        /// <summary>
        /// Serialize the Query object as JSON 
        /// </summary>
        /// <returns>A JSON string</returns>
        public virtual string ToJsonRequest()
        {
            string serializedRequest = string.Empty;
            List<Type> listOfTypes = new List<Type>();

            DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(Query), listOfTypes);
            using (MemoryStream stream = new MemoryStream())
            {
                jsonSerializer.WriteObject(stream, this);
                serializedRequest = Encoding.GetEncoding("iso-8859-1").GetString(stream.ToArray());                
            }         
  
            return serializedRequest;
        }

        #endregion

        /// <summary>
        /// Based on the values of object properties, returns a well formed LiveSearch query expression
        /// </summary>
        /// <returns>A Live Search query string </returns>
        protected virtual string LiveSearchExpression()
        {
            return "( " + this.Text + " )" + this.Augmentation;
        }
    }

}
